home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / asm_msc1.arc / LIST.ASM < prev    next >
Assembly Source File  |  1988-11-20  |  14KB  |  399 lines

  1.          PAGE    60,132
  2.          TITLE   LIST --- Replace TYPE and MORE commands
  3. ;==============================================================================
  4. ; Name:     LIST, display contents of an ASCII file.
  5. ; Syntax:
  6. ;           LIST  <[d:][path]filename[.ext]>
  7. ; Input:
  8. ;           An ASCII file of any size may be listed, however only the
  9. ;           first 80 bytes of each record is displayed.
  10. ;
  11. ;           After the 'More?' prompt, enter a CR to continue, or
  12. ;           any other character to terminate.
  13. ; Output:
  14. ;           Logical records (ending in LF and/or CR) are placed into
  15. ;           the screen buffer.
  16. ; Notes:
  17. ;           Written for the IBM PC by Vernon Buerg, November 1983,
  18. ;           and is supplied for public domain use.
  19. ;             
  20. ; Revised:  Robert S. Russell, Bootstrap Creations, Walnut Creek, Calif.
  21. ;           December 3, 1983 to allow enough space in buffer for filename
  22. ;           so that a path may also be specified.  Also removed a bug which 
  23. ;           caused the system to lock if a carriage return is entered in 
  24. ;           response to the filename prompt.
  25. ;
  26. ;==============================================================================
  27. ;
  28. STACK    SEGMENT PARA STACK 'STACK'
  29.          DB      128 DUP (0)
  30. STACK    ENDS
  31. ;
  32. DATA     SEGMENT PUBLIC PARA 'DATA'
  33. ASKFILE  DB      13,10,'Enter [d:][path]filename[.ext]:$'             ;RSR
  34. CLEAR    DB      27,'[2J$'
  35. PROMPT   DB      27,'[25;1H','More?$'
  36. EOFMSG   DB      27,'[25;1HEnd-of-file$'
  37. CODE2    DB      13,10,'File not found$'                              ;RSR
  38. CODE4    DB      13,10,'Too many open files$'                         ;RSR
  39. KEYIN    DB      0            ;keyboard buffer size
  40. KEYOUT   DB      0            ;keyboard length read
  41. FILENAME DB      45 DUP (0)   ;drive:\path\filename.ext               ;RSR
  42. HANDLE   DW      0            ;file handle from open
  43. COL      DW      1            ;current display column
  44. ROW      DW      2            ;current display row
  45. INDEX    DW      0            ;offset in buffer to record
  46. ;
  47. OPENMSG  DB      13,10,'Open code: '                                  ;RSR
  48. OPENCODE DW      '00'
  49.          DB      '  $'
  50. RECLEN   DW      0            ;length of current record
  51. RECADDR  DW      0            ;addr of i/o buffer
  52. ;
  53. SWITCH1  DB      0
  54. EOR      EQU     1            ;end-of-record
  55. SWITCH2  DB      0
  56. NODATA   EQU     2            ;null record
  57. NUMLF    DB      0            ;line feed count
  58. NUMCR    DB      0            ;C/R count
  59. WORK     DB      256 DUP (?)  ;current logical record
  60. DATA     ENDS
  61. ;
  62. ZBUFFER  SEGMENT PARA PUBLIC 'BUFFER'
  63. RECORDS  DB      65535 DUP (?)
  64. ZBUFFER  ENDS
  65. ;
  66. BIOS     SEGMENT AT 40H       ;set up labels to determine
  67.          ORG     10H          ;color or monochrome card
  68. EQFLAG   LABEL   WORD
  69.          ORG     4AH          ;40 or 80 column display
  70. NCLMS    LABEL   WORD
  71.          ORG     63H
  72. A6845    LABEL   WORD         ;points to video card ports
  73. BIOS     ENDS
  74. ;
  75.          PAGE
  76. CSEG     SEGMENT PARA PUBLIC 'CODE'
  77.          ASSUME  CS:CSEG,DS:DATA,SS:STACK,ES:ZBUFFER
  78. LIST     PROC    FAR
  79.          PUSH    DS           ;save for linkage
  80.          XOR     AX,AX        ;clear for return
  81.          PUSH    AX           ;put in stack
  82. ;
  83.          MOV     AX,DATA      ;Addr of work areas
  84.          MOV     DS,AX        ;Set data segment reg
  85. ;
  86.          PUSH    DS           ;Save DS
  87.          XOR     CX,CX        ;clear hi-byte
  88.          MOV     CL,BYTE PTR ES:[80H]  ;Length of command parm
  89.          DEC     CL           ;For ending CR
  90.          CMP     CL,0         ;Any parm string?
  91.          JLE     GETNAME      ;No, ask for it
  92. ;
  93.          MOV     SI,82H       ;Offset to command parm string
  94.          MOV     DI,OFFSET FILENAME
  95.          MOV     AX,DS        ;Swap DS/ES
  96.          MOV     BX,ES
  97.          MOV     DS,BX        ;Copy command string
  98.          MOV     ES,AX
  99.          REP     MOVSB
  100.          POP     DS           ;Restore DS
  101.          JMP     OPEN
  102.          PAGE
  103. ;  No filename supplied with command
  104. ;
  105. GETNAME: POP     DS
  106. RETRYNAME:                                                              ;RSR
  107.          MOV     DX,OFFSET ASKFILE    ;Prompt for file name
  108.          MOV     AH,9
  109.          INT     21H
  110.          MOV     AH,0AH       ;Buffered kybd input DOS req
  111.          MOV     DX,OFFSET KEYIN
  112.          MOV     KEYIN,44     ;Size of buffer                           ;RSR
  113.          INT     21H
  114. ;
  115.          XOR     BX,BX
  116.          MOV     BL,KEYOUT    ;Number of chars read
  117.          CMP     BL,0
  118.          JE      RETRYNAME                                              ;RSR
  119.          MOV     FILENAME[BX],0 ;overlay CR
  120.          PAGE
  121. ;
  122. OPEN:    MOV     DX,OFFSET FILENAME      ;file to open
  123.          MOV     AX,0         ;for read only                            ;RSR
  124.          MOV     AH,3DH       ;open a file
  125.          INT     21H
  126.          MOV     HANDLE,AX    ;save file handle
  127. ;
  128.          JNC     INIT         ;if OPEN okay
  129.          MOV     DX,OFFSET CODE2
  130.          CMP     AL,2         ;is it 'file not found'?
  131.          JE      ERROR
  132.          MOV     DX,OFFSET CODE4                                        ;RSR
  133.          CMP     AL,4         ;is it 'too many open files'?             ;RSR
  134.          JE      ERROR
  135. ;
  136.          AAM
  137.          XCHG    AL,AH
  138.          OR      OPENCODE,AX
  139.          MOV     DX,OFFSET OPENMSG
  140. ERROR:   MOV     AH,9
  141.          INT     21H          ;say OPEN FAILED
  142.          RET
  143.          PAGE
  144. ;
  145. ; Initialize buffer to EOF stoppers
  146. ;
  147. INIT:    MOV     BX,ZBUFFER   ;addr of I/O area
  148.          MOV     RECADDR,BX   ;save it
  149.          MOV     DX,OFFSET CLEAR
  150.          MOV     AH,9
  151.          INT     21H          ;to clear screen
  152. ;
  153. READAGN: MOV     CX,65535     ;number of bytes to clear
  154.          MOV     ES,RECADDR
  155. ;
  156. STOPPER: MOV     DI,CX
  157.          MOV     ES:BYTE PTR[DI],1AH    ;fill with stoppers
  158.          LOOP    STOPPER
  159.          PAGE
  160. ;
  161. ; Read a block  (64K)
  162. ;
  163.          MOV     BX,HANDLE       ;get file handle from open
  164.          MOV     DX,RECADDR      ;offset to record buffer
  165.          PUSH    DS
  166.          MOV     DS,DX           ;set data segment ptr
  167.          SUB     DX,DX           ; with zero offset
  168.          MOV     CX,65534        ;number of bytes to read
  169.          MOV     AH,3FH          ;read from a file
  170.          INT     21H
  171. ;
  172.          POP     DS
  173. ;        MOV     BX,AX           ;Save length read
  174.          MOV     SWITCH1,0       ;reset EOR flag
  175.          MOV     INDEX,0         ;offset into buffer
  176.          CMP     AX,0            ;Any bytes read?
  177.          JNE     READ            ;Yes, list the buffer
  178.          JMP     CLOSE           ;No, all done
  179. ;
  180. ; Set next row and column for next display line
  181. ;
  182. READ:    MOV     CX,RECLEN       ;set column and row
  183.          INC     CX              ; for next record
  184.          MOV     AX,ROW
  185.          DEC     AX
  186.          CMP     NUMLF,0         ;record ended in LF?
  187.          JE      SET             ;no, have col/row
  188.          INC     AX              ;yes, row stays where it is
  189.          MOV     CX,1            ; and in column 1
  190. ;
  191. SET:     MOV     ROW,AX          ;set row
  192.          MOV     COL,CX          ;set column
  193. ;
  194. ; Extract next logical record from display
  195. ;
  196. GETNEXT: CALL    SCAN_BUF        ;Scan for logical record
  197.          MOV     CX,RECLEN       ;Record size
  198.          SUB     CL,NUMLF        ;for LF
  199.          SUB     CL,NUMCR        ;for CR
  200.          MOV     RECLEN,CX
  201.          CMP     CX,0            ;blank line?
  202.          JE      GETROW          ;yes, increment row only
  203. ;
  204.          LEA     SI,WORK         ;addr of record
  205.          MOV     AX,ROW          ;destination row
  206.          CALL    PRINT           ;put into screen buffer
  207. ;
  208. GETROW:  MOV     AX,ROW          ;get row again
  209.          INC     AX              ;bump to next row
  210.          MOV     ROW,AX          ;save row number
  211.          CMP     AL,25           ;exceeded screen?
  212.          JNE     TESTEOR         ;no, read next record
  213. ;
  214.          MOV     DX,OFFSET PROMPT
  215.          MOV     AH,9
  216.          INT     21h             ;say 'More?'
  217. ;
  218. ; Wait for keyboard input
  219. ;
  220.          MOV     AH,12           ;clear console
  221.          MOV     AL,7            ;and get a char
  222.          INT     21H             ;pause for enter
  223.          CMP     AL,0DH          ;want to quit?
  224.          JNE     CLOSE           ;yes, clean up
  225. ;
  226.          MOV     ROW,2           ;no, reset to first row
  227.          MOV     AX,ROW
  228. ;
  229.          MOV     DX,OFFSET CLEAR
  230.          MOV     AH,9
  231.          INT     21H             ;to clear screen
  232. ;
  233.          LEA     SI,WORK         ;addr of record
  234.          MOV     AX,1            ;put last line on top
  235.          MOV     CX,RECLEN
  236.          CALL    PRINT           ;put into screen buffer
  237. ;
  238. TESTEOR: TEST    SWITCH1,EOR     ;end-of-records?
  239.          JZ      READ
  240.          JMP     READAGN         ;yes, read next block
  241. ;
  242. CLOSE:   MOV     BX,HANDLE       ;file handle from open
  243.          MOV     AH,3EH          ;close a file handle
  244.          INT     21H
  245. ;
  246.          MOV     DX,OFFSET EOFMSG
  247.          MOV     AH,9
  248.          INT     21H             ;to say done
  249. ;
  250.          RET
  251.          PAGE
  252. SCAN_BUF PROC    NEAR
  253. ;
  254. ; Function: Scan the buffer for special characters and copy wanted
  255. ;        data to field WORK. A logical record ends in an LF and/or CR.
  256. ;
  257. ; Input: ZBUFFER (RECORDS) contains a block of data from the file
  258. ;        INDEX is the current offset to a logical record
  259. ; Output:
  260. ;        WORK contains a logical record
  261. ;        NUMLF contains number of line feeds (ignored)
  262. ;        NUMCR contains number of carriage returns (ignored)
  263. ;        RECLEN contains length of logical record
  264. ; Notes: Tabs are replaced by blanks;
  265. ;        lines beginning with hex-F are ignored
  266. ;
  267.          PUSH    ES
  268.          PUSH    CX
  269.          PUSH    SI
  270.          PUSH    DI
  271.          TEST    SWITCH1,EOR
  272.          JZ      SCAN1
  273.          JMP     SCAN_END
  274. ;
  275. SCAN1:   XOR     CX,CX
  276.          XOR     DI,DI
  277.          AND     SWITCH2,0FFH-NODATA
  278.          MOV     NUMLF,0         ;reset LF indicator
  279.          MOV     NUMCR,0         ;zero CR counter
  280.          MOV     AX,ZBUFFER
  281.          MOV     ES,AX           ;set addr of I/O buffer segment
  282. ;
  283. SCAN2:   MOV     SI,INDEX
  284.          MOV     AL,RECORDS[SI]  ;Get a byte
  285.          CMP     AL,1AH          ;End of buffer?
  286.          JNE     SCAN3
  287.          MOV     RECLEN,CX
  288.          OR      SWITCH1,EOR     ;Indicate end-of-records
  289.          JMP     SCAN_END
  290. ;
  291. SCAN3:   CMP     AL,9H           ;Is it TAB?
  292.          JNE     SCAN4
  293.          MOV     AL,' '          ;Yes, replace with blank
  294. ;
  295. SCAN4:   MOV     WORK[DI],AL     ;Store character
  296.          INC     DI              ;Increment pointer
  297.          INC     CX              ;Increment counter
  298.          INC     INDEX           ;Increment counter
  299. ;
  300.          CMP     AL,0DH          ;Is it a CR?
  301.          JNE     SCAN5
  302.          INC     NUMCR           ;Yes, increment counter
  303. SCAN5:   CMP     AL,' '
  304.          JE      SCAN7
  305.          CMP     AL,0AH          ;Is it line feed?
  306.          JNE     SCAN6
  307.          INC     NUMLF
  308.          JMP     SCAN8
  309. SCAN6:   OR      SWITCH2,NODATA  ;Non-space found
  310. ;
  311. SCAN7:   CMP     CX,255          ;Record too big?
  312.          JE      SCAN8           ;Chop record at 255 bytes
  313.          JMP     SCAN2
  314. ;
  315. SCAN8:   MOV     RECLEN,CX
  316.          CMP     WORK,0FH        ;If record begins with "sun"
  317.          JNE     SCAN9           ; symbol, skip it
  318.          JMP     SCAN1
  319. ;
  320. SCAN9:   TEST    SWITCH2,NODATA  ;If nothing but spaces found,
  321.          JNZ     SCAN_END        ; read another record
  322.          JMP     SCAN1
  323. ;
  324. SCAN_END:
  325.          POP     DI
  326.          POP     SI
  327.          POP     CX
  328.          POP     ES
  329.          RET
  330. ;
  331. SCAN_BUF ENDP
  332. ;
  333.          PAGE
  334.          ASSUME  CS:CSEG,DS:DATA,ES:NOTHING
  335. PRINT    PROC    NEAR
  336.          PUSH    ES
  337.          PUSH    DI
  338.          PUSH    DX
  339.          PUSH    SI
  340. ;
  341.          MOV     DI,COL          ;set column
  342.          DEC     DI              ;adjust for zero offset
  343.          DEC     AX              ;adjust row too
  344.          CMP     CL,0            ;null string?
  345.          JE      EXIT            ;if so,do nothing, Else,
  346. ;
  347.          MOV     BX,BIOS         ;get ready to determine card type
  348.          MOV     ES,BX           ;and number of columns
  349.          MUL     ES:NCLMS        ;AX = column * words per line
  350.          ADD     DI,AX           ;DI = words from start of screen
  351.          SHL     DI,1            ;adjust for attribute bytes
  352. ;
  353.          MOV     DX,ES:A6845     ;point to 6845 base port
  354.          ADD     DX,6            ;point to status port
  355. ;
  356. ;CX has the count of characters to write,
  357. ;SI points to the string data,
  358. ;DI points to a screen position
  359. ;
  360.          MOV     AX,0B800H       ;default to color card
  361.          MOV     BX,ES:EQFLAG
  362.          AND     BX,30H
  363.          CMP     BX,30H          ;is it monochrome?
  364.          JNE     CARDOK          ;no, go
  365.          MOV     AX,0B000H       ;yes, set for monochrome
  366. CARDOK:  MOV     ES,AX           ;points ES to video
  367. ;
  368. ;  DS:SI => first character of string
  369. ;  ES:DI => screen memory to display it
  370. ;  CX    => number of characters to display
  371. ;  DX    => status port of video card
  372. ;
  373. ;-------- Wait for horzontal retrace
  374. TESTLO:  IN      AL,DX           ;get status
  375.          TEST    AL,1            ;is it low?
  376.          JNZ     TESTLO          ;no, keep checking
  377.          CLI                     ;turn off interrupts
  378. TESTHI:  IN      AL,DX           ;get status
  379.          TEST    AL,1            ;is it high?
  380.          JZ      TESTHI          ;no, keep checking
  381. ;-------- Okay to write to screen now (no 'hash')
  382.          MOVSB                   ;[DS:DI]->[ES:DI],DI++,SI++,CX--
  383.          INC     DI              ;skip the attribute byte
  384.          LOOP    TESTLO          ;do till end of string
  385.          STI                     ;turn interrupts back on
  386. ;
  387. EXIT:    POP     SI
  388.          POP     DX
  389.          POP     DI
  390.          POP     ES
  391.          RET
  392. ;
  393. PRINT    ENDP
  394. ;
  395. LIST     ENDP
  396. CSEG     ENDS
  397. ;
  398.          END     LIST
  399.